package com.transaction.simulate.service.impl;

import com.transaction.common.util.ConstUtil;
import com.transaction.common.util.FileUtil;
import com.transaction.common.util.ParamsUtil;
import com.transaction.simulate.mapper.ChannelMapper;
import com.transaction.simulate.model.dto.Channel;
import com.transaction.simulate.model.dto.TextFile;
import com.transaction.simulate.model.vo.ChannelAccountVo;
import com.transaction.simulate.service.*;
import com.transaction.simulate.util.AssembleFileUtil;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.io.File;
import java.util.*;

@Service
public class FileServiceImpl implements FileService {

    private static Logger LOGGER = LoggerFactory.getLogger(FileServiceImpl.class);

    @Autowired
    private ChannelMapper channelMapper;

    @Autowired
    private AccountService accountService;

    @Autowired
    private FundService fundService;

    @Autowired
    private TransService transService;

    @Autowired
    private ElContractService elContractService;

    @Autowired
    private InterfaceService interfaceService;

    @Override
    public List<TextFile> getAnalysisFileList(String channelCode, String transDate) {
        LOGGER.info("获得渠道{}，日期{},解析文件的列表",channelCode,transDate);
        List<TextFile> retValue = new ArrayList<>();
        Channel channel = channelMapper.selectChannelByChannelCode(channelCode);
        String creatorName = channel.getCreatorName();
        String sendPath = FileUtil.buildSendFilePath(channelCode, transDate,ConstUtil.TRANSACTION_SIMULATE);
        String receivePath = FileUtil.buildReceiveFilePath(channelCode, transDate,ConstUtil.TRANSACTION_SIMULATE);
        getAnalysisFileList(channelCode,creatorName, transDate,sendPath,retValue);
        getAnalysisFileList(channelCode,creatorName, transDate,receivePath,retValue);
        return retValue;
    }

    private void getAnalysisFileList(String channelCode, String creatorName, String transDate, String filePath, List<TextFile> retValue) {
        File fileDir = new File(filePath);
        File[] files = fileDir.listFiles();
        if(files.length != 0){
            for(File file : files){
                TextFile textFile = new TextFile();
                String fileName = file.getName();
                if(!fileName.endsWith(ConstUtil.FILE_SUFFIX)){
                    LOGGER.info("已解析文件:{}",fileName);
                    continue;
                }
                textFile.setChannelCode(channelCode);
                textFile.setFilePath(filePath);
                textFile.setCreatorName(creatorName);
                textFile.setTransDate(transDate);
                textFile.setFileName(fileName);
                textFile.setFileSize(file.length()/1024);
                retValue.add(textFile);
            }
        }
    }


    @Override
    public String analysisFile(TextFile v){
        String channelCode = v.getChannelCode();
        String transDate = v.getTransDate();
        String filePath = v.getFilePath() ;
        String fileName = v.getFileName();

        LOGGER.info("解析文件的渠道{},日期{},文件路径{},文件名{}",
                channelCode,transDate,filePath,fileName);

        File file = new File(filePath + fileName);
        try{
            return AssembleFileUtil.analysisFile(channelCode,transDate,fileName,file);
        }catch(Exception e){
            LOGGER.info(ParamsUtil.getErrorMsg(e));
            return "解析文件:"+fileName+"异常!";
        }

    }

    @Override
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRED)
    public void handleAnalysisFileData(String channelCode,String transDate,String fileType,List<Map<String, Object>> dataList) {
        LOGGER.info("插入信息{}",dataList);
        switch (fileType){
            case ConstUtil.FILE_TYPE_01:
                LOGGER.info("插入渠道账户信息");
                accountService.insertChannelAccount(channelCode,dataList);
                break;
            case ConstUtil.FILE_TYPE_02:
                LOGGER.info("处理渠道账户信息");
                accountService.handleConfirmChannelAccount(channelCode,dataList);
                break;
            case ConstUtil.FILE_TYPE_03:
                LOGGER.info("插入渠道交易信息表");
                transService.insertChannelTrans(channelCode,dataList);
                break;
            case ConstUtil.FILE_TYPE_04:
                LOGGER.info("处理渠道交易信息");
                transService.handleConfirmChannelTrans(channelCode,dataList);
                break;
            case ConstUtil.FILE_TYPE_05:
                LOGGER.info("插入对账表");
                transService.insertReconciliation(channelCode,dataList);
                break;
            case ConstUtil.FILE_TYPE_06:
                LOGGER.info("插入分红表");
                transService.insertBonus(channelCode,dataList);
                break;
            case ConstUtil.FILE_TYPE_07:
                LOGGER.info("插入、更新产品信息表");
                fundService.insertFundInfo(channelCode,transDate,dataList);
                break;
            case ConstUtil.FILE_TYPE_43:
                LOGGER.info("插入电子合同信息表");
                elContractService.insertElContract(channelCode,dataList);
                break;
            case ConstUtil.FILE_TYPE_44:
                LOGGER.info("更新电子合同信息表");
                elContractService.updateElContract(channelCode,dataList);
                break;
        }
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED,rollbackFor = Exception.class)
    public void generateChannelFile(ChannelAccountVo channelAccountVo) {
        String channelCode = channelAccountVo.getChannelCode();
        String transDate = channelAccountVo.getTransDate();
        List<String> dateRange = channelAccountVo.getDateRange();
        LOGGER.info("生成渠道{}，日期{},数据日期在{}范围内的文件",channelCode,transDate,dateRange.toString());

        //获得渠道勾选的文件
        Channel channel = channelMapper.selectChannelByChannelCode(channelCode);
        String dealFileTypes = channel.getDealFileTypes();
        List<String> dealFileList = Arrays.asList(dealFileTypes.split(","));

        dealFileList.forEach(v->{
            switch(v){
                case ConstUtil.FILE_TYPE_01:
                    accountService.generateChannelAccountFile(channelCode,transDate,dateRange);
                    break;
                case ConstUtil.FILE_TYPE_03:
                    transService.generateChannelTransFile(channelCode,transDate,dateRange);
                    break;
                case ConstUtil.FILE_TYPE_31:
                    transService.generateChannel31ElContractFile(channelCode,transDate,dateRange);
                    break;
                case ConstUtil.FILE_TYPE_43:
                    transService.generateChannel43ElContractFile(channelCode,transDate,dateRange);
                    break;
                case ConstUtil.FILE_TYPE_R1:
                    accountService.generateChannelAccountR1File(channelCode,transDate,dateRange);
                    break;
                case ConstUtil.FILE_TYPE_X1:
                    accountService.generateChannelAccountX1File(channelCode,transDate,dateRange);
                    break;
                case ConstUtil.FILE_TYPE_X3:
                    accountService.generateChannelAccountX3File(channelCode,transDate,dateRange);
                    break;
            }
        });
        //生成索引文件
        String fileDir = FileUtil.buildSendFilePath(channelCode,transDate,ConstUtil.TRANSACTION_SIMULATE);
        AssembleFileUtil.generateIndexFile(fileDir,channelCode,transDate);
    }

    @Override
    public List<TextFile> getChannelFile(Map<String, Object> map){
        List<TextFile> retList = new ArrayList<>();

        String channelCode = MapUtils.getString(map,"channelCode");
        String transDate = MapUtils.getString(map,"transDate");
        String filePath = FileUtil.buildSendFilePath(channelCode,transDate,ConstUtil.TRANSACTION_SIMULATE);
        File file = new File(filePath);
        File[] files = file.listFiles();
        Arrays.stream(files).forEach(v->{
            TextFile text = new TextFile();
            text.setFileName(v.getName());
            text.setFileSize(v.length()/1024);
            retList.add(text);
        });
        return retList;
    }

    @Override
    public Map<String,Object> getChannelFileDetail(Map<String, Object> map) {
        String channelCode = MapUtils.getString(map,"channelCode");
        String transDate = MapUtils.getString(map,"transDate");
        String fileTypes = MapUtils.getString(map,"fileTypes");

        Map<String,Object> retMap = new HashMap<>();
        LOGGER.info("获得渠道{}，日期{},文件类型{}的详细文件内容",channelCode,transDate,fileTypes);
        if(StringUtils.isNotEmpty(fileTypes) && StringUtils.isNotEmpty(channelCode)
        && StringUtils.isNotEmpty(transDate)){
            List<String> fileType = Arrays.asList(fileTypes.split(","));
            //获得表头
            fileType.forEach(v->{
                Channel channel = channelMapper.selectChannelByChannelCode(channelCode);
                String versionCode = channel.getVersionCode();
                List<Map<String,String>> tableHead = interfaceService.selectInterfaceMapByCode(v + versionCode);

                //获得内容
                String fileName = AssembleFileUtil.generateFileName(channel,v,transDate);
                String filePath = FileUtil.buildSendFilePath(channelCode,transDate,ConstUtil.TRANSACTION_SIMULATE);
                File file = new File(filePath + fileName);
                List<Map<String,Object>> tableData = null;

                retMap.put("table" + v + "Head",tableHead);
                retMap.put("table" + v + "Data",tableData);
            });
        }

        return retMap;
    }
}
